// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "TypeUtility.h"
#include "Weapon/WeaponDefault.h"
#include "TDSCharacter.generated.h"

UCLASS(Blueprintable)
class ATDSCharacter : public ACharacter
{
    GENERATED_BODY()

public:
    ATDSCharacter();

    // Called every frame.
    virtual void Tick(float DeltaSeconds) override;
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

    virtual void SetupPlayerInputComponent(class UInputComponent* NewInputComponent) override;

    /** Returns TopDownCameraComponent subobject **/
    FORCEINLINE class UCameraComponent* GetTopDownCameraComponent() const { return TopDownCameraComponent; }
    /** Returns CameraBoom subobject **/
    FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }

private:
    /** Top down camera */
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
    class UCameraComponent* TopDownCameraComponent;

    /** Camera boom positioning the camera above the character */
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
    class USpringArmComponent* CameraBoom;

public:
    // Cursor
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cursor")
    UMaterialInterface* CursorMaterial = nullptr;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cursor")
    FVector CursorSize = FVector(20.0f, 40.0f, 40.0f);

    UDecalComponent* CurrentCursor = nullptr;

    // Movement
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement")
    EMovementState MovementState = EMovementState::Run_State;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement")
    FCharacterSpeed MovementInfo;

    // Weapon
    AWeaponDefault* CurrentWeapon = nullptr;

    // for Demo
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Demo")
    FName InitWeaponName;

    // Inputs
    UFUNCTION()
    void InputAxisX(float Value);
    UFUNCTION()
    void InputAxisY(float Value);
    UFUNCTION()
    void InputAttackPressed();
    UFUNCTION()
    void InputAttackReleased();

    float AxisX = 0.0f;
    float AxisY = 0.0f;
    // Tick Function
    UFUNCTION()
    void MovementTick(float DeltaTime);
    UFUNCTION()
    void ZoomingTick(float DeltaTime);

    // Func
    UFUNCTION(BlueprintCallable)
    void ZoomIn();

    UFUNCTION(BlueprintCallable)
    void ZoomOut();

    // Property
    // zooming
    float ZoomStep = 200.0f;
    float MaxHight = 1200.0f;
    float MinHight = 680.0f;
    float TargHight = 900.0f;

    // Character State
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement")
    bool SprintRunEnabled = false;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement")
    bool WalkEnabled = false;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement")
    bool AimEnabled = false;

    // Update State Character
    UFUNCTION(BlueprintCallable)
    void CharacterUpdate();
    UFUNCTION(BlueprintCallable)
    void ChangeMovementState();

    UFUNCTION(BlueprintCallable)
    UDecalComponent* GetCursorToWorld();

    // WeaponFunc
    UFUNCTION(BlueprintCallable)
    void InitWeapon(FName IdWeapon);
    UFUNCTION(BlueprintCallable)
    void TryReloadWeapon();

    UFUNCTION(BlueprintCallable)
    AWeaponDefault* GetCurrentWeapon();
    UFUNCTION(BlueprintCallable)
    void AttackCharEvent(bool bIsFiring);
};
